package jwdt.xadmin.flow.action;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jwdt.xadmin.system.bean.TUser;

import org.snaker.engine.access.Pager;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.HistoryOrder;
import org.snaker.engine.model.TaskModel;

import com.ezerg.util.JsonUtil;
import com.ezerg.util.StringUtil;
import com.ezerg.web.Form;
import com.ezerg.web.Module;
import com.ezerg.web.Page;
import com.ezerg.web.annotation.Controller;
import com.ezerg.web.annotation.RequestMapping;

/**
 * 通用流程controller类，主要有以下方法：
 * 1、通用的all视图路由
 * 2、通用的流程启动、任务执行方法
 * 3、通用的审批视图路由及审批处理
 */
@Controller("/xadmin/flow")
public class FlowAction extends SnakerAction {
	/**
	 * 流程实例查询
	 * @param f
	 * @param m
	 * @return
	 */
	@RequestMapping("/order")
	public Page doOrder(Form f, Module m) {
		Pager<HistoryOrder> page = new Pager<HistoryOrder>();
		page.setPageNo(f.getInt("pageNo", 1));
		engine.query().getHistoryOrders(page, new QueryFilter());
		f.add("page", page);
		return m.jspPage(url.concat("order.jsp"));
	}
	
	/**
	 * 级联删除实例
	 * @param f
	 * @param m
	 * @return
	 */
	@RequestMapping("/orderDel")
	public Page doOrderDel(Form f, Module m) {
		//String processId = f.getString(PARA_PROCESSID);
		String orderId = f.getString(PARA_ORDERID);
		engine.order().cascadeRemove(orderId);
		return m.redirectPage(url.concat("order.do"));
	}
	
	/**
	 * 抄送实例已读
	 */
	@RequestMapping("/ccread")
	public Page doCcread(Form f, Module m) {
		TUser user = (TUser) f.getSession("userInfo");
		List<String> list = new ArrayList<String>();
		list.add(user.getUsername());
		String[] assignees = new String[list.size()];
		list.toArray(assignees);
		engine.order().updateCCStatus(f.getString("id"), assignees);
		return m.redirectPage(URL_ACTIVETASK);
	}
	
	/**
	 * 处理流程启动或任务执行，并且将表单数据保存至实例、任务变量中
	 * 变量类型根据表单字段的首字母决定，类型分别为:S字符型,I整形,L常整形,B布尔型,D日期型,N浮点型
	 * 执行规则根据method的值决定，值分别为:0执行,-1驳回或跳转,1转主办,2转协办
	 * 适用于演示流程，或者是无业务字段的正式流程
	 */
	@RequestMapping("/process")
	@SuppressWarnings("unchecked")
	public Page doProcess(Form f, Module m) {
		TUser user = (TUser) f.getSession("userInfo");
		Map<String, Object> params = new HashMap<String, Object>();
		Enumeration<String> paraNames = f.getRequest().getParameterNames();
		while (paraNames.hasMoreElements()) {
			String element = paraNames.nextElement();
			int index = element.indexOf("_");
			if(index == -1) {
				params.put(element, f.getString(element));
			} else {
				char type = element.charAt(0);
				String name = element.substring(index + 1);
				Object value = null;
				switch(type) {
				case 'S':
					value = f.getString(element);
					break;
				case 'I':
					value = f.getInt(element);
					break;
				case 'L':
					value = f.getString(element);
					break;
				case 'B':
					value = f.getString(element);
					break;
				case 'D':
					value = f.getString(element);
					break;
				case 'N':
					value = Double.parseDouble(f.getString(element));
					break;
				default:
					value = f.getString(element);
					break;
				}
				params.put(name, value);
			}
		}
		String processId = f.getString(PARA_PROCESSID);
		String orderId = f.getString(PARA_ORDERID);
		String taskId = f.getString(PARA_TASKID);
		String nextOperator = f.getString(PARA_NEXTOPERATOR);
		if (StringUtil.nullOrBlank(orderId) && StringUtil.nullOrBlank(taskId)) {
			startAndExecute(processId, user.getUsername(), params);
		} else {
			int method = f.getInt(PARA_METHOD, 0);
			switch(method) {
			case 0://任务执行
				execute(taskId, user.getUsername(), params);
				break;
			case -1://驳回、任意跳转
				executeAndJump(taskId, user.getUsername(), params, f.getString(PARA_NODENAME));
				break;
			case 1://转办
				if(!StringUtil.nullOrBlank(nextOperator)) {
					transferMajor(taskId, user.getUsername(), nextOperator.split(","));
				}
				break;
			case 2://协办
				if(!StringUtil.nullOrBlank(nextOperator)) {
					transferAidant(taskId, user.getUsername(), nextOperator.split(","));
				}
				break;
			default:
				execute(taskId, user.getUsername(), params);
				break;
			}
		}
		String ccOperator = f.getString(PARA_CCOPERATOR);
		if(!StringUtil.nullOrBlank(ccOperator)) {
			engine.order().createCCOrder(orderId, user.getUsername(), ccOperator.split(","));
		}
		return redirectActiveTask(f, m);
	}
	
	/**
	 * 通用的流程展现页面入口
	 * 将流程中的各环节表单以tab+iframe方式展现
	 */
	@RequestMapping("/all")
	public Page doAll(Form f, Module m) {
		String processId = f.getString(PARA_PROCESSID);
		String orderId = f.getString(PARA_ORDERID);
		String taskId = f.getString(PARA_TASKID);
		if(!StringUtil.nullOrBlank(processId)) {
			f.add("process", engine.process().getProcessById(processId));
		}
		if(!StringUtil.nullOrBlank(orderId)) {
			f.add("order", engine.query().getOrder(orderId));
		}
		if(!StringUtil.nullOrBlank(taskId)) {
			f.add("task", engine.query().getTask(taskId));
		}
		//
		return m.jspPage(url.concat("all.jsp"));
	}
	
	/**
	 * 节点信息以json格式返回
	 * all页面以节点信息构造tab及加载iframe
	 */
	@RequestMapping("/node")
	public Page doNode(Form f, Module m) {
		String processId = f.getString(PARA_PROCESSID);
		org.snaker.engine.entity.Process process = engine.process().getProcessById(processId);
		List<TaskModel> models = process.getModel().getModels(TaskModel.class);
		return m.writePage(f, JsonUtil.toJson(models));
	}
	
}
